/** @jsxImportSource @emotion/react */
import * as React from "react";
import {
    Text, InputLine, Input, Layer, CheckSwitch, Button, Popover, PopoverRefer, IconChevronDown, PopoverContent, PopoverDescription,
    MenuList, MenuItem, PopoverClose, IconX, useToast, IconButton, IconTruck, LineColumn,
} from "customize-easy-ui-component";
import {InspectRecordLayout, InternalItemProps, useItemInputControl,} from "../../common/base";
import queryString from "query-string";
import {tableSetInp} from "../../../common/tool";

export declare type InputMoreCallback = (inp: any, setInp: React.Dispatch<React.SetStateAction<any>>) => React.ReactNode;
/**@property name : 附录显示名称, 和页面逻辑开关代码上需保持一致的。
 * @property ha : Hash路由标签
 * @property na : 表示不在【结论报告附页】当中出现的吗，但都出现在目录中的。不在附录表也没有安排目录表这页的也行。 na:正好相反，怪啊；
 * @property ml : 该分项在报告【目录】中的文本显示题目。
 * @property ol :原始记录的标题。
 * @property om :仅出现在原始记录的目录。 om=ture: 只是在记录目录存在的，但是在正式报告目录却不显示的。 na=表示在两个目录页都不存在。{规定：记录目录集合包含报告的列表}
 * @property do : 默认有做的分项报告
 *其它字段： page ，apx: 正式报告的标注。  op，oa: 打印原始记录的标注。
 * @property zs: 证书，在前面 不在目录？ na:可替代。且顺序是在代码布局体现的。
 * @property dd: 不在目录的，可附页中必须显示的【目的】支持结论报告附页的用户添加。 na:可替代。
 * 报告中实际打印顺序看代码：
 * 原平台testlogcfg.ses的 "contlist" :[ {"contname":}, ]列出全部分项。  而"mainpage":[ ]扣除"addpage":[]后的是固定的必须展示。 nosavepage无关的；
 const VsProjects默认2=[];
 正式报告的目录"repcontlist"	"allreportpage"， 记录打印的目录是=旧的 contlist， allpage。
 * */
interface ProjectRProps  extends InternalItemProps{
    //不允许动态增加减少固定的分项配置
    config: any[];      //有注入分项目详细列表；
    // resultlist?: any[];       //结果录入 可选的列表；
    // jgsm?: boolean;     //需要编辑录入 结果和说明的。
    inpCB?: InputMoreCallback;
    //没有原始记录目录录入
    nrec?: boolean;
}
//原始记录用的 项目列表： 可兼容报告俩种的目录
export const ProjectR=
    React.forwardRef((
        { children, show ,alone=true,label,config,inpCB,nrec}:ProjectRProps,  ref
    ) => {
        const toast = useToast();
        const getInpFilter = React.useCallback((par: any) => {
            //仅仅页面上用的路由hash字段 "ha": 不需要存储数据库给报告的。
            const VsProjects_configPure=config.map(
                one=>{ const { ha, ...other}=one;
                    return {...other} }
            );
            //初始化的 Projects=空 -> 缺省值:要求挑选的大项目; 怎能增加，不允许删除和修改默认项目名字。
            const {Projects =VsProjects_configPure } =par||{};
            return {Projects};
        }, []);
        const {inp, setInp} = useItemInputControl({ ref });
        const qs= queryString.parse(window.location.search);
        const [viewHas, setViewHas] = React.useState<boolean>(false);
        const [seq, setSeq] = React.useState<number | null>(Number(qs?.from));   //表對象的當前一條。
        const [obj, setObj] = React.useState<any>();        //Projects数组的各个对象
        React.useEffect(() => {
            let size = inp?.Projects?.length;
            let ifrom = Number(qs?.from);
            if (ifrom >= 0 && ifrom < size) {
                setSeq(ifrom);    //导致初始化显示最后一个seq
                setObj(inp?.Projects?.[ifrom]);
            } else {
                setSeq(null);
                setObj(null);
            }
        }, [qs?.from ]);
        //这上面副作用：,inp?.Projects不能随意增加 依赖项哦，也不能用[qs])替代，qs会导致点击修改菜单后也会重复刷新的。【不要加】inp?.Projects依赖项，导致尾部插入的会跳到qs?.from那一条显示，不合理。
        function onModifySeq(idx:number,it:any){
            setObj(it);
            setSeq(idx);
        };
        function onDeleteSeq(idx:number,it:any){
            let fixSize =config.length;
            if(idx<fixSize)  return;        //【不是用户添加的】不允许删除
            inp?.Projects?.splice(idx,1);
            setInp({...inp,Projects: [...inp?.Projects] });
            setSeq(null);
        };
        function onInsertSeq(idx:number,it:any){
            let fixSize =config.length;
            if(idx<fixSize)  return;    //不允许从默认项目列表中间插入自定义的东西
            inp?.Projects?.splice(idx,0, obj);
            setInp({...inp,Projects:[...inp?.Projects] });
            setSeq(idx);
        };
        function onAddSeq(idx:number){
            let size =inp?.Projects?.push(obj);
            setInp( (inp?.Projects&&{...inp,Projects:[...inp?.Projects] } )  || {...inp,Projects:[obj] } );
            //应该跳到最后一条：不能停留倒数第二条 当前from 当前按钮那条；
            setSeq((inp?.Projects&&(size-1))  || 0 );
        };
        const clearProjectCatalog = React.useCallback(() => {
            setInp({...inp, Projects:undefined });
            toast({title: "目录表被清空", subtitle: "需要重新设置!", intent: "warning"});
        }, [inp,setInp,toast]);
        //本对象组件：是共享的，状态交互注意。 参数：fixed 表示用户自己添加的吗
        const editor=(fixed: boolean, tail: boolean) => <Layer elevation={"sm"} css={{ padding: '0.25rem' }}>
            <div>
                <LineColumn column={6}>
                    <InputLine label={`有做该项目吗:`}>
                        <CheckSwitch  checked= {obj?.do || false}
                                      onChange={e =>setObj({...obj, do: (obj?.do? undefined:true)} ) } />
                    </InputLine>
                    {!fixed &&
                        <InputLine label={`检验项目:`}>
                            <Input   value={obj?.name ||''}
                                     onChange={e =>setObj({...obj, name: e.currentTarget.value} ) } />
                        </InputLine>
                    }
                    { !obj?.na && inpCB && inpCB(obj,setObj)}
                    <InputLine label={`页号`}>
                        <Input   value={obj?.page ||''}
                                 onChange={e =>setObj({...obj, page: e.currentTarget.value} ) } />
                    </InputLine>
                    <InputLine label={`附页、附图`}>
                        <Input   value={obj?.apx ||''}
                                 onChange={e =>setObj({...obj, apx: e.currentTarget.value} ) } />
                    </InputLine>
                    {!nrec && <>
                        <InputLine label={`记录-页号`}>
                            <Input   value={obj?.op ||''}
                                     onChange={e =>setObj({...obj, op: e.currentTarget.value} ) } />
                        </InputLine>
                        <InputLine label={`记录-附图附页`}>
                            <Input   value={obj?.oa ||''}
                                     onChange={e =>setObj({...obj, oa: e.currentTarget.value} ) } />
                        </InputLine>
                    </>}
                    {!fixed && <InputLine label={`不在目录中显示该项目:`}>
                        <CheckSwitch  checked= {obj?.na || false}
                                      onChange={e =>setObj({...obj, na: (obj?.na? undefined:true)} ) } />
                    </InputLine>
                    }
                </LineColumn>
                <Button onPress={() => {
                    if(seq !== null) {
                        inp?.Projects?.splice(seq, 1, obj);
                        setInp({ ...inp, Projects: [...inp?.Projects] });
                    }
                    else setInp({ ...inp, Projects: [...inp?.Projects ,obj] });
                } }
                >{tail? `新增一条` : `改一条就确认`}</Button>
            </div>
        </Layer>;
        //项目明细编辑器的显示：依赖Projects数组索引i来判定的。页面上名义的顺序序号不等于这个的，要转换？链接生成时刻就要敲定了。新增加的又删除导致序号跳变?【默认】项目不允许删除而且在前面。
        const myTable=<div>
            {inp?.Projects?.map((a:any,i:number)=>{
                if((viewHas && a?.do) || !viewHas)
                    return <React.Fragment  key={i}>
                        <div css={{display: 'flex',alignItems: 'center',flexWrap: 'wrap'
                        }}>{`${i+1}`}
                            <Popover>
                                <PopoverRefer>
                                   <Button  size="md" iconAfter={<IconChevronDown />} variant="ghost" css={{whiteSpace:'unset'}}>
                                            {`${a?.name||'？'} [${a?.do? '有做':'没做'}] `}
                                   </Button>
                                </PopoverRefer>
                                <PopoverContent>
                                    <PopoverDescription>
                                        <MenuList>
                                            <MenuItem onPress={()=>onModifySeq(i,a)}>修改</MenuItem>
                                            <MenuItem onPress={()=>onDeleteSeq(i,a)}>刪除这条</MenuItem>
                                            <MenuItem onPress={()=>onInsertSeq(i,a)}>插入一条</MenuItem>
                                            <MenuItem onPress={()=>onAddSeq(i)}>末尾新增一条</MenuItem>
                                        </MenuList>
                                    </PopoverDescription>
                                    <PopoverClose>
                                        <IconX/>
                                    </PopoverClose>
                                </PopoverContent>
                            </Popover>
                            {!a?.do && <IconButton  icon={<IconTruck />} variant="ghost" size="md" label='有做'
                                          onPress={() => { tableSetInp('Projects',i, inp,setInp,'do',true)}}/>
                            }
                        </div>
                        {i===seq && editor(i<config.length, false) }
                    </React.Fragment>;
                else return null;
            }) }
        </div>;
        return (
            <InspectRecordLayout inp={inp} setInp={setInp}  getInpFilter={getInpFilter} show={show}
                                 alone={alone}  label={label!}>
                { children }
                <Text  variant="h5">
                    {label}-包括的项目：
                </Text>
                <Button intent='primary' onPress={() => setViewHas(!viewHas)}
                >{viewHas? `显示全部项目`: `仅显示有做的项目`}</Button>
                默认项目表的部分不能删除，不能改名字;
                <hr/>
                {myTable}
                { seq===null && editor(false, true) }
                <Text  variant="h5">
                    有些是不在附页中体现的但却在目录中有的其页号需设定。
                </Text>
                想清空所有项目（分项）和目录的配置（谨慎使用！）：
                <Button intent='danger' onPress={() => {
                    clearProjectCatalog();
                }}>重新初始化</Button>
            </InspectRecordLayout>
        );
} );
